<html>
<head><meta charset="utf-8"><title>multiple closure borrows · t-compiler · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/index.html">t-compiler</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/multiple.20closure.20borrows.html">multiple closure borrows</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="220994527"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/multiple%20closure%20borrows/near/220994527" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> devsnek <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/multiple.20closure.20borrows.html#220994527">(Dec 27 2020 at 05:24)</a>:</h4>
<p>is it safe to say that as long as closures are implemented the way they are, allowing multiple closures to borrow the same variable (assuming some way of telling rust that the lifetime is valid and that only one of the closures can be invoked at any time), is fundamentally impossible?</p>



<a name="220996393"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/multiple%20closure%20borrows/near/220996393" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> devsnek <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/multiple.20closure.20borrows.html#220996393">(Dec 27 2020 at 06:33)</a>:</h4>
<p>actually if a closure was <code>!Sync</code> and <code>!Send</code>, couldn't all the borrows be <code>*mut</code> instead of <code>&amp;mut</code> so they're realized when the closure executes instead of when it is declared</p>



<a name="220996395"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/multiple%20closure%20borrows/near/220996395" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aman Arora <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/multiple.20closure.20borrows.html#220996395">(Dec 27 2020 at 06:33)</a>:</h4>
<p><span class="user-mention silent" data-user-id="219805">devsnek</span> <a href="#narrow/stream/131828-t-compiler/topic/multiple.20closure.20borrows/near/220994527">said</a>:</p>
<blockquote>
<p>is it safe to say that as long as closures are implemented the way they are, allowing multiple closures to borrow the same variable (assuming some way of telling rust that the lifetime is valid and that only one of the closures can be invoked at any time), is fundamentally impossible?</p>
</blockquote>
<p>So we are working on a feature (capture_disjoint_fields, rfcs#2229) if enabled will affect what a closure borrows. </p>
<p>Eg: </p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nb">String</span>::<span class="n">new</span><span class="p">(),</span><span class="w"> </span><span class="nb">String</span>::<span class="n">new</span><span class="p">());</span><span class="w"></span>

<span class="kd">let</span><span class="w"> </span><span class="n">c1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">   </span><span class="kd">let</span><span class="w"> </span><span class="n">mut_string</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">t</span><span class="p">.</span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
<span class="p">};</span><span class="w"></span>

<span class="kd">let</span><span class="w"> </span><span class="n">c2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">   </span><span class="kd">let</span><span class="w"> </span><span class="n">mut_string</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">t</span><span class="p">.</span><span class="mi">1</span><span class="p">;</span><span class="w"></span>
<span class="p">};</span><span class="w"></span>
</code></pre></div>
<p>Now without the feature, this won't compile because <code>t</code> is borrowed completely by <code>c1</code> and therefore <code>t</code> can't be borrowed by <code>c2</code>. However you enable the feature then this becomes valid code. That said you can't have <code>c2</code> capture <code>t.0</code> because that will be trying to borrow the same place twice mutably<br>
.</p>



<a name="220996440"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/multiple%20closure%20borrows/near/220996440" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> devsnek <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/multiple.20closure.20borrows.html#220996440">(Dec 27 2020 at 06:34)</a>:</h4>
<p>i'm thinking more like</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
<span class="n">foo</span><span class="p">.</span><span class="n">bar</span><span class="p">(</span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="p">});</span><span class="w"> </span><span class="c1">// !Sync+!Send</span>
<span class="n">foo</span><span class="p">.</span><span class="n">baz</span><span class="p">(</span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="p">});</span><span class="w"> </span><span class="c1">// !Sync+!Send</span>
<span class="n">foo</span><span class="p">.</span><span class="n">run</span><span class="p">();</span><span class="w"> </span><span class="c1">// runs above closures in some pattern</span>
</code></pre></div>
<p>it would seem this is theoretically possible, just not something rustc knows how to do</p>



<a name="220996454"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/multiple%20closure%20borrows/near/220996454" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aman Arora <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/multiple.20closure.20borrows.html#220996454">(Dec 27 2020 at 06:35)</a>:</h4>
<p>I'm not familar with Send and Sync to answer that question, but I should look into this</p>



<a name="220996494"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/multiple%20closure%20borrows/near/220996494" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> devsnek <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/multiple.20closure.20borrows.html#220996494">(Dec 27 2020 at 06:36)</a>:</h4>
<p>It's basically just saying the closure can't be shared or moved to another thread</p>



<a name="220996502"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/multiple%20closure%20borrows/near/220996502" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aman Arora <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/multiple.20closure.20borrows.html#220996502">(Dec 27 2020 at 06:37)</a>:</h4>
<p>Ah, the feature shouldn't affect the behavior here because it only adds support for  precise paths to be captured</p>



<a name="220996509"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/multiple%20closure%20borrows/near/220996509" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> devsnek <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/multiple.20closure.20borrows.html#220996509">(Dec 27 2020 at 06:37)</a>:</h4>
<p>yeah, my point was when the whole resource is borrowed in both cases, like <code>x</code> in my example</p>



<a name="221005181"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/multiple%20closure%20borrows/near/221005181" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/multiple.20closure.20borrows.html#221005181">(Dec 27 2020 at 11:28)</a>:</h4>
<p><span class="user-mention" data-user-id="219805">@devsnek</span> no need to go <code>*mut</code>, <code>&amp;Cell</code> and the like suffice for that.<br>
There is also the option to give an additional env parameter to the closure, so that you capture all the "use once" stuff inside a variable a then explicitly pass it to each closure when called</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>